| dhcpv6_pd |bool | 1 | DHCPv6 stateful addressing hands out IA_PD - Internet Address - Prefix Delegation (PD) |
| dhcpv6_pd_preferred |bool | 0 | Set the DHCPv6-PD Preferred (P) flag in outgoing ICMPv6 RA message PIOs (RFC9762); requires `dhcpv6` and `dhcpv6_pd`. |
| dhcpv6_pd_min_len |integer| - | Minimum prefix length to delegate with IA_PD (value is adjusted if needed to be greater than the interface prefix length). Range [1,62] |
-| router |list |`<local address>`| Routers to announce, accepts IPv4 only |
+| router |list |`<local address>`| IPv4 addresses of routers on a given subnet (provided via DHCPv4, should be in order of preference) |
| dns |list |`<local address>`| DNS servers to announce, accepts IPv4 and IPv6 |
| dnr |list |disabled| Encrypted DNS servers to announce, `<priority> <domain name> [<comma separated IP addresses> <SvcParams (key=value)>...]` |
| dns_service |bool | 1 | Announce the address of interface as DNS service if the list of dns is empty |
free(iface->dns_addrs6);
free(iface->dns_search);
free(iface->upstream);
- free(iface->dhcpv4_router);
+ free(iface->dhcpv4_routers);
free(iface->dhcpv6_raw);
free(iface->dhcpv4_ntp);
free(iface->dhcpv6_ntp);
unsigned rem;
blobmsg_for_each_attr(cur, c, rem) {
- struct in_addr addr4;
+ struct in_addr addr4, *tmp;
if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false))
continue;
if (inet_pton(AF_INET, blobmsg_get_string(cur), &addr4) == 1) {
- iface->dhcpv4_router = realloc(iface->dhcpv4_router,
- (++iface->dhcpv4_router_cnt) * sizeof(*iface->dhcpv4_router));
- if (!iface->dhcpv4_router)
+ tmp = realloc(iface->dhcpv4_routers,
+ (iface->dhcpv4_routers_cnt + 1) * sizeof(*iface->dhcpv4_routers));
+ if (!tmp)
goto err;
- iface->dhcpv4_router[iface->dhcpv4_router_cnt - 1] = addr4;
- } else
+ iface->dhcpv4_routers = tmp;
+ iface->dhcpv4_routers[iface->dhcpv4_routers_cnt++] = addr4;
+ } else {
error("Invalid %s value configured for interface '%s'",
iface_attrs[IFACE_ATTR_ROUTER].name, iface->name);
+ }
}
}
case DHCPV4_OPT_ROUTER:
iov[IOV_ROUTER].iov_len = sizeof(reply_router);
- if (iface->dhcpv4_router_cnt) {
- reply_router.len = iface->dhcpv4_router_cnt * sizeof(*iface->dhcpv4_router);
- iov[IOV_ROUTER_ADDR].iov_base = iface->dhcpv4_router;
+ if (iface->dhcpv4_routers_cnt) {
+ reply_router.len = iface->dhcpv4_routers_cnt * sizeof(*iface->dhcpv4_routers);
+ iov[IOV_ROUTER_ADDR].iov_base = iface->dhcpv4_routers;
} else {
reply_router.len = sizeof(iface->dhcpv4_own_ip.addr.in);
iov[IOV_ROUTER_ADDR].iov_base = &iface->dhcpv4_own_ip.addr.in;
struct in_addr dhcpv4_start_ip;
struct in_addr dhcpv4_end_ip;
struct odhcpd_ipaddr dhcpv4_own_ip;
- struct in_addr *dhcpv4_router;
- size_t dhcpv4_router_cnt;
+ struct in_addr *dhcpv4_routers; // IPv4 addresses for routers on this subnet
+ size_t dhcpv4_routers_cnt; // Count of router addresses
bool dhcpv4_forcereconf;
// DNS